package view.common;

import java.awt.image.BufferedImage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;

import java.sql.SQLException;
import java.sql.Timestamp;

import java.text.DateFormat;
import java.text.SimpleDateFormat;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import java.util.Map;

import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import javax.el.ELContext;
import javax.el.ExpressionFactory;
import javax.el.ValueExpression;

import javax.faces.application.FacesMessage;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;

import javax.imageio.ImageIO;

import oracle.adf.model.BindingContext;
import oracle.adf.model.binding.DCBindingContainer;
import oracle.adf.model.binding.DCIteratorBinding;
import oracle.adf.share.ADFContext;
import oracle.adf.view.rich.component.rich.RichPopup;

import oracle.binding.BindingContainer;
import oracle.binding.OperationBinding;

import oracle.jbo.Row;
import oracle.jbo.ViewCriteria;
import oracle.jbo.ViewCriteriaRow;
import oracle.jbo.ViewObject;
import oracle.jbo.domain.Number;

import oracle.jbo.uicli.binding.JUCtrlListBinding;

import org.apache.myfaces.trinidad.model.UploadedFile;
import org.apache.myfaces.trinidad.render.ExtendedRenderKitService;
import org.apache.myfaces.trinidad.util.Service;

import javax.faces.application.FacesMessage.Severity;

import javax.faces.application.ViewHandler;
import javax.faces.context.ExternalContext;

import javax.servlet.http.HttpServletRequest;

import oracle.adf.view.rich.component.rich.input.RichInputDate;
import oracle.adf.view.rich.component.rich.input.RichInputText;
import oracle.adf.view.rich.context.AdfFacesContext;

import oracle.jbo.RowIterator;

import oracle.jbo.ViewCriteriaItem;
import oracle.jbo.common.JboCompOper;
import oracle.jbo.uicli.binding.JUCtrlRangeBinding;

import org.apache.myfaces.trinidad.context.RequestContext;

import org.apache.myfaces.trinidad.event.SelectionEvent;

import view.common.search.AdvancedSearchGroup;


public class Utils {

    public static final String DATEFORMAT = "dd/MM/yyyy";

    private static final String[] defaultFileExtension =
        new String[] { "doc", "docx", "xls", "xlsx", "ppt", "pptx", "odt",
                       "ods", "odp", "pdf", "zip", "rar", "txt", "jpg", "bmp",
                       "jpe", "jpeg", "gif", "png" };

    private static final String[] defaultImageExtension =
        new String[] { "jpg", "jpeg", "gif", "png"};
    public Utils() {
        super();
    }

    public static boolean checkDefaultFileExtension(String fileName) {
        return checkFileExtension(fileName, defaultFileExtension);
    }

    public static String getDefaultFileExtension() {
        String result = "";
        for (int i = 0; i < defaultFileExtension.length; i++) {
            result = result + defaultFileExtension[i] + ",";
        }
        return result.substring(0, result.length() - 1);
    }

    public static boolean checkDefaultImageExtension(String fileName) {
        return checkFileExtension(fileName, defaultImageExtension);
    }

    public static String getDefaultImageExtension() {
        String result = "";
        for (int i = 0; i < defaultImageExtension.length; i++) {
            result = result + defaultImageExtension[i] + ",";
        }
        return result.substring(0, result.length() - 1);
    }

    public static boolean checkFileExtension(String fileName,
                                             String[] fileExtensions) {
        if (fileExtensions != null)
            return checkFileExtension(fileName, Arrays.asList(fileExtensions));
        return false;
    }

    public static boolean checkFileExtension(String fileName,
                                             List<String> listFileExtension) {
        boolean result = false;
        if (fileName != null && listFileExtension != null) {
            int index = fileName.lastIndexOf(".");
            if (index != -1) {
                String fileExtension =
                    fileName.substring(index + 1, fileName.length());
                fileExtension = fileExtension.toLowerCase();
                if (listFileExtension.contains(fileExtension)) {
                    result = true;
                }
            }
        }
        return result;
    }

    public static String getStringFromArrayString(String[] array) {
        String result = "";
        if (array != null) {
            for (String str : array) {
                result = result + str + ",";
            }
        }
        if (result.endsWith(",")) {
            result = result.substring(0, result.length() - 1);
        }
        return result;
    }

    public static Timestamp toTimeStamp(String date) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
            Date convertedDate = dateFormat.parse(date);
            Timestamp timestamp = toTimeStamp(convertedDate);
            return timestamp;
        } catch (Exception e) {
            return null;
        }
    }

    public static Timestamp TimeStamp(String date) {
        try {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date convertedDate = dateFormat.parse(date);
            Timestamp timestamp = toTimeStamp(convertedDate);
            return timestamp;
        } catch (Exception e) {
            return null;
        }
    }

    public static String getFormatDateByObject(Object obj) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
            String sValue = dateFormat.format(obj);
            return sValue;
        } catch (Exception ex) {
            return obj.toString();
        }
    }

    public static String FormatDateByObject(Object obj) {
        try {
            DateFormat dateFormat = new SimpleDateFormat(DATEFORMAT);
            DateFormat Format = new SimpleDateFormat("yyyy-MM-dd");
            Date date = Format.parse(obj.toString());
            String sValue = dateFormat.format(date);
            return sValue;
        } catch (Exception ex) {
            return obj.toString();
        }
    }

    public static Timestamp toTimeStamp(java.util.Date date) {
        if (date == null) {
            return null;
        }
        Timestamp timestamp = new Timestamp(date.getTime());
        return timestamp;
    }

    public static void setPageFlowScope(String key, Object value) {
        Map pageFlowScope =
            RequestContext.getCurrentInstance().getPageFlowScope();
        Object myObject = pageFlowScope.put(key, value);
    }

    public static Object getPageFlowScope(String key) {
        Map pageFlowScope =
            RequestContext.getCurrentInstance().getPageFlowScope();
        Object myObject = pageFlowScope.get(key);
        return myObject;
    }

    /**
     * TanBD
     * Kiểm tra độ dài chuỗi trong khoảng
     * @param sVal
     * @param iFrom
     * @param iTo
     * @return
     */
    public static Boolean checkTextLength(String sVal, int iFrom, int iTo) {
        if (sVal.length() < iFrom || sVal.length() > iTo) {
            return false;
        }
        return true;
    }

    /**
     * TanBD
     * Kiểm tra trùng dữ liệu
     * @param attributeValue
     * @param attributeName
     * @param iterName
     * @param lang
     * @return
     */
    public static Boolean checkExisted(String attributeValue,
                                       String attributeName, String iterName,
                                       Object lang) {
        DCIteratorBinding viewIterator = getIteratorBinding(iterName);
        ViewObject vo = viewIterator.getViewObject();
        ViewCriteria vc = vo.createViewCriteria();
        vc.setName("VCIteratorExist");

        ViewCriteriaRow vcRow = vc.createViewCriteriaRow();
        ViewCriteriaItem rowViewCriteriaItem =
            vcRow.ensureCriteriaItem(attributeName);
        rowViewCriteriaItem.setOperator(JboCompOper.OPER_EQ);
        rowViewCriteriaItem.setValue(attributeValue.toUpperCase());
        if (lang != null) {
            vcRow.setConjunction(ViewCriteriaRow.VC_CONJ_AND);
            rowViewCriteriaItem.setUpperColumns(true);
            ViewCriteriaItem rowViewCriteriaItem1 =
                vcRow.ensureCriteriaItem("NgonNgu");
            rowViewCriteriaItem1.setOperator(JboCompOper.OPER_EQ);
            rowViewCriteriaItem1.setValue(lang.toString());
        }
        vc.addRow(vcRow);
        vo.getViewCriteriaManager().removeApplyViewCriteriaName("VCIteratorExist");
        vo.applyViewCriteria(vc);
        vo.executeQuery();
        if (vo.getAllRowsInRange().length > 0) {
            return true;
        }
        return false;
    }

    /**
     * TanBD
     * Tìm thành phần dạng UIComponent trong View
     * @param name
     * @return
     */
    public static UIComponent getUIComponent(String name) {
        FacesContext facesCtx = FacesContext.getCurrentInstance();
        return facesCtx.getViewRoot().findComponent(name);
    }

    // reset all the child uicomponents

    public static void resetValueInputItems(AdfFacesContext adfFacesContext,
                                            UIComponent component) {
        List<UIComponent> items = component.getChildren();
        for (UIComponent item : items) {

            resetValueInputItems(adfFacesContext, item);

            if (item instanceof RichInputText) {
                RichInputText input = (RichInputText)item;
                if (!input.isDisabled()) {
                    input.resetValue();
                    adfFacesContext.addPartialTarget(input);
                }
                ;
            } else if (item instanceof RichInputDate) {
                RichInputDate input = (RichInputDate)item;
                if (!input.isDisabled()) {
                    input.resetValue();
                    adfFacesContext.addPartialTarget(input);
                }
                ;
            }
        }
    }

    /**
     * @comment
     * @creator thang beo
     * @param myfile
     * @param filePath
     * @param fileId
     * @return
     */
    public static Boolean fileUpload(UploadedFile myfile, File fullPath,
                                     String fileId) {
        boolean result = false;
        FileOutputStream output = null;
        try {
            if (fullPath.exists() == false) {
                fullPath.mkdirs();
            }
            byte buffer[] = new byte[1024];
            int size = 0;
            InputStream input = myfile.getInputStream();
            String fileName = myfile.getFilename();
            output =
                    new FileOutputStream(new File(fullPath, fileId + "_" + fileName));
            while ((size = input.read(buffer)) != -1) {
                output.write(buffer);
            }
            result = true;

        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        } finally {
            if (output != null) {
                try {
                    output.flush();
                    output.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    public static boolean fileUpload(InputStream in, ENUM_CAU_HINH_KHOA thuMuc,
                                     String cauHinhIteratorName,
                                     Row htFileRow) {
        boolean result = false;
        FileOutputStream output = null;
        try {
            String tenFile =
                htFileRow.getAttribute("Id") + "_" + htFileRow.getAttribute("TenFile");
            String rootString =
                ENUM_CAU_HINH_KHOA.FILE_ROOT.getValue(cauHinhIteratorName);
            String dirString = thuMuc.getValue(cauHinhIteratorName);
            String duongDan = dirString + "/" + tenFile;
            duongDan = duongDan.replace("\\", "/");
            while (duongDan.contains("//")) {
                duongDan = duongDan.replace("//", "/");
            }
            htFileRow.setAttribute("DuongDan", duongDan);
            File rootFile = new File(rootString);
            File dirFile = new File(rootFile, dirString);
            if (dirFile.exists() == false) {
                dirFile.mkdirs();
            }
            File file = new File(dirFile, tenFile);
            byte buffer[] = new byte[1024];
            int size = 0;
            output = new FileOutputStream(file);
            while ((size = in.read(buffer)) != -1) {
                output.write(buffer, 0, size);
            }
            in.close();
            result = true;
        } catch (Exception e) {
            result = false;
            e.printStackTrace();
        } finally {
            if (output != null) {
                try {
                    output.flush();
                    output.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * @param myfile
     * @param imagePath string
     */
    public static Boolean imageUpload(UploadedFile myfile, File imagePath,
                                      String fileId) {
        Boolean b = false;
        try {
            InputStream inputStream = myfile.getInputStream();
            BufferedImage input = ImageIO.read(inputStream);
            String fileName = myfile.getFilename();
            String ext =
                fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            if (ext.toLowerCase().equals("jpg") ||
                ext.toLowerCase().equals("jpeg") ||
                ext.toLowerCase().equals("gif") ||
                ext.toLowerCase().equals("png")) {
                File outputFile =
                    new File(imagePath + "/" + fileId + "_" + fileName);
                if (outputFile.getParentFile().exists() == false) {
                    outputFile.getParentFile().mkdirs();
                }
                ImageIO.write(input, ext, outputFile);
                b = true;
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return b;
    }

    /**
     * @param file
     * @param filePath
     * @param fileIterator
     * @param detailIterator
     * @param operationType
     * @param maUngDung
     */
    public static void processUpload(UploadedFile file, File filePath,
                                     String fileIterator,
                                     String detailIterator, int operationType,
                                     ENUM_MA_UNG_DUNG maUngDung,
                                     String fileId) {
        DCIteratorBinding fileIterator1 =
            Utils.getIteratorBinding(fileIterator);

        DCIteratorBinding detailIterator1 =
            Utils.getIteratorBinding(detailIterator);
        Object OldfileId = null;
        OldfileId = detailIterator1.getCurrentRow().getAttribute("FileId");
        //Xoa file cu trong truong hop cap nhat
        if (operationType == 1) {
            if (fileId != null) {
                if (OldfileId != null) {
                    String[] arrFiles = OldfileId.toString().split(",");
                    for (int i = 0; i < arrFiles.length; i++) {
                        fileIterator1.setCurrentRowWithKeyValue(arrFiles[i]);
                        String duongdan =
                            fileIterator1.getCurrentRow().getAttribute("DuongDan").toString();
                        File oldPath =
                            new File(String.valueOf(ENUM_CAU_HINH_KHOA.FILE_ROOT.KHOA_HT()),
                                     duongdan);
                        fileDelete(oldPath);
                    }
                }
            }
        }
        //Them thong tin file moi vao db
        fileIterator1.getCurrentRow().setAttribute("TenFile",
                                                   fileId + "_" + file.getFilename());
        fileIterator1.getCurrentRow().setAttribute("DuongDan",
                                                   filePath.toString().replace("\\",
                                                                               "/") +
                                                   "/" + fileId + "_" +
                                                   file.getFilename());
        fileIterator1.getCurrentRow().setAttribute("MaUngDung",
                                                   maUngDung.getMaUngDung());
        detailIterator1.getCurrentRow().setAttribute("FileId",
                                                     fileIterator1.getCurrentRow().getAttribute("Id"));

    }

    /**
     * @param file
     * @param filePath
     * @param fileIterator
     * @param detailIterator
     * @param maUngDung
     */
    public static void DeleteOldFile(UploadedFile file, File filePath,
                                     String fileIterator,
                                     String detailIterator,
                                     ENUM_MA_UNG_DUNG maUngDung,
                                     String fileId) {
        DCIteratorBinding fileIterator1 =
            Utils.getIteratorBinding(fileIterator);

        DCIteratorBinding detailIterator1 =
            Utils.getIteratorBinding(detailIterator);
        Object OldfileId = detailIterator1.getCurrentRow().getAttribute("FileId");
        //Xoa vat ly file cu trong truong hop cap nhat
            if (fileId != null) {
                if (OldfileId != null) {
                    String[] arrFiles = OldfileId.toString().split(",");
                    for (int i = 0; i < arrFiles.length; i++) {
                        fileIterator1.setCurrentRowWithKeyValue(arrFiles[i]);
                        String duongdan =
                            fileIterator1.getCurrentRow().getAttribute("DuongDan").toString();
                        File oldPath =
                            new File(String.valueOf(ENUM_CAU_HINH_KHOA.FILE_ROOT.KHOA_HT()),
                                     duongdan);
                        fileDelete(oldPath);
                    }
                }
            }
        //Them thong tin file moi vao db
//        fileIterator1.getCurrentRow().setAttribute("TenFile",
//                                                   fileId + "_" + file.getFilename());
//        fileIterator1.getCurrentRow().setAttribute("DuongDan",
//                                                   filePath.toString().replace("\\",
//                                                                               "/") +
//                                                   "/" + fileId + "_" +
//                                                   file.getFilename());
//        fileIterator1.getCurrentRow().setAttribute("MaUngDung",
//                                                   maUngDung.getMaUngDung());

    }

    /**
     * @param dirName
     * @param zipInput
     */
    public static void unZipFile(String dirName, ZipInputStream zipInput) {
        try {
            File dir = new File(dirName);
            ZipEntry zipEntry = zipInput.getNextEntry();
            while (zipEntry != null) {
                if (zipEntry.isDirectory() == false) {
                    File fileEx = new File(dir, zipEntry.getName());
                    if (fileEx.getParentFile().exists() == false) {
                        fileEx.getParentFile().mkdirs();
                    }
                    FileOutputStream fileExOut = new FileOutputStream(fileEx);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = zipInput.read(buffer)) != -1) {
                        fileExOut.write(buffer, 0, len);
                    }
                    fileExOut.flush();
                    fileExOut.close();
                }
                zipEntry = zipInput.getNextEntry();
            }
            zipInput.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static ArrayList<String> unZipFile(String dirName, String prefixId,
                                              ZipInputStream zipInput) {
        ArrayList<String> fileList = new ArrayList<String>();
        try {
            File dir = new File(dirName);
            ZipEntry zipEntry = zipInput.getNextEntry();
            while (zipEntry != null) {
                if (zipEntry.isDirectory() == false) {
                    File fileName =
                        new File(prefixId + "_" + zipEntry.getName());
                    File fileEx = new File(dir, fileName.toString());
                    if (fileEx.getParentFile().exists() == false) {
                        fileEx.getParentFile().mkdirs();
                    }
                    FileOutputStream fileExOut = new FileOutputStream(fileEx);
                    byte[] buffer = new byte[1024];
                    int len = 0;
                    while ((len = zipInput.read(buffer)) != -1) {
                        fileExOut.write(buffer, 0, len);
                    }
                    fileList.add(fileName.toString());
                    fileExOut.flush();
                    fileExOut.close();
                }
                zipEntry = zipInput.getNextEntry();
            }
            zipInput.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return fileList;
    }

    public static void search(String iteratorName,
                              Map<String, Object>... mapPredicates) {
        try {
            DCIteratorBinding iter = getIteratorBinding(iteratorName);
            ViewObject vo =
                iter.getRowSetIterator().getRowSet().getViewObject();
            ViewCriteria vc = vo.createViewCriteria();
            int count = mapPredicates.length;
            for (int i = 0; i < count; i++) {
                Map<String, Object> mapPredicate = mapPredicates[i];
                ViewCriteriaRow vcr = vc.createViewCriteriaRow();
                Iterator it = mapPredicate.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String)it.next();
                    Object value = mapPredicate.get(key);
                    if (value != null) {
                        if (value instanceof Date) {
                            Date date = (Date)value;
                            Timestamp sqlTimestamp =
                                new java.sql.Timestamp(date.getTime());
                            value = new oracle.jbo.domain.Date(sqlTimestamp);
                        }
                        vcr.setAttribute(key, value);
                    }
                }
                vc.add(vcr);
            }
            vc.setUpperColumns(true);
            vo.getViewCriteriaManager().clearViewCriterias();
            vo.getViewCriteriaManager().applyViewCriteria(vc);
            iter.executeQuery();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public static void search(String iteratorName,
                              List<Map<String, Object>> mapPredicates) {
        try {
            DCIteratorBinding iter = getIteratorBinding(iteratorName);
            ViewObject vo =
                iter.getRowSetIterator().getRowSet().getViewObject();
            ViewCriteria vc = vo.createViewCriteria();
            for (Map<String, Object> mapPredicate : mapPredicates) {
                ViewCriteriaRow vcr = vc.createViewCriteriaRow();
                Iterator it = mapPredicate.keySet().iterator();
                while (it.hasNext()) {
                    String key = (String)it.next();
                    Object value = mapPredicate.get(key);
                    if (value != null) {
                        if (value instanceof Date) {
                            Date date = (Date)value;
                            Timestamp sqlTimestamp =
                                new java.sql.Timestamp(date.getTime());
                            value = new oracle.jbo.domain.Date(sqlTimestamp);
                        }
                        vcr.setAttribute(key, value);
                    }
                }
                vc.add(vcr);
            }
            vc.setUpperColumns(true);
            vo.getViewCriteriaManager().clearViewCriterias();
            vo.getViewCriteriaManager().applyViewCriteria(vc);
            iter.executeQuery();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    public static void searchadvanced(String iteratorName,
                                      List<AdvancedSearchGroup> listAdvancedSearchGroup) {
        DCIteratorBinding iterator = Utils.getIteratorBinding(iteratorName);
        ViewObject vo = iterator.getViewObject();
        ViewCriteria vc = vo.createViewCriteria();
        AdvancedSearchGroup.setViewCriteria(listAdvancedSearchGroup, vc);
        vo.getViewCriteriaManager().clearViewCriterias();
        vo.getViewCriteriaManager().applyViewCriteria(vc);
        vo.executeQuery();
    }

    /**
     * TanBD
     * Lấy Row đã chọn trong mảng
     * @param listId
     * @param selectedArray
     * @return
     */
    public static List<Row> getSelectedRow(String listId,
                                           int[] selectedArray) {
        List<Row> listRow = new ArrayList();
        BindingContainer bc =
            BindingContext.getCurrent().getCurrentBindingsEntry();
        JUCtrlListBinding listBinding = (JUCtrlListBinding)bc.get(listId);
        Map<Integer, Row> mapId = new HashMap();
        int listCount = listBinding.getRowIterator().getRowCount();
        for (int i = 0; i < listCount; i++) {
            mapId.put(i, listBinding.getRowAtRangeIndex(i));
        }
        for (int i = 0; i < selectedArray.length; i++) {
            Row row = mapId.get(selectedArray[i]);
            if (row != null) {
                listRow.add(row);
            }
        }
        return listRow;
    }

    /**
     * @param Id
     * @param iteratorName
     * @return
     */
    public static String getValueById(String keyValue, String iteratorName) {
        String vl = null;
        if (keyValue != null) {
            DCIteratorBinding iterator1 =
                Utils.getIteratorBinding(iteratorName);
            iterator1.setCurrentRowWithKeyValue(keyValue);
            vl =
 String.valueOf(iterator1.getCurrentRow().getAttribute("TenFile"));
        }
        return vl;
    }

    /**
     * @param f
     */
    public static void fileDelete(File f) {
        try {
            f.delete();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Refresh a View Iterator
     * @param iteratorName
     */
    public static void iteratorRefresh(String iteratorName) {
        try {
            DCBindingContainer dcBinding =
                (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
            DCIteratorBinding ViewIterator =
                (DCIteratorBinding)dcBinding.get(iteratorName);
            ViewIterator.getViewObject().clearCache();
            int oldMode = ViewIterator.getViewObject().getQueryMode();
            ViewIterator.getViewObject().setQueryMode(ViewObject.QUERY_MODE_SCAN_DATABASE_TABLES);
            ViewIterator.executeQuery();
            ViewIterator.getViewObject().setQueryMode(oldMode);
            ViewIterator.refresh(DCIteratorBinding.RANGESIZE_UNLIMITED);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Execute an operator
     * @param operator
     * @return null
     */
    public static List execute(String operator) {
        try {
            BindingContainer bindings = getBindings();
            OperationBinding operationBinding =
                bindings.getOperationBinding(operator);
            Object result = operationBinding.execute();
            if (operationBinding.getErrors() != null &&
                operationBinding.getErrors().size() > 0) {
                return operationBinding.getErrors();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * Show an adf popup
     * @param popup
     */
    public static void showPopup(RichPopup popup) {
        FacesContext context = FacesContext.getCurrentInstance();
        ExtendedRenderKitService service =
            Service.getRenderKitService(context, ExtendedRenderKitService.class);
        service.addScript(context,
                          "var popup = AdfPage.PAGE.findComponent('" + popup.getClientId(context) +
                          "'); popup.show();");
    }

    public static void closePopup(RichPopup popup) {
        FacesContext context = FacesContext.getCurrentInstance();
        ExtendedRenderKitService service =
            Service.getRenderKitService(context, ExtendedRenderKitService.class);
        service.addScript(context,
                          "var popup = AdfPage.PAGE.findComponent('" + popup.getClientId(context) +
                          "'); popup.close();");
    }

    public final static Severity MSG_FATAL = FacesMessage.SEVERITY_FATAL;
    public final static Severity MSG_ERROR = FacesMessage.SEVERITY_ERROR;
    public final static Severity MSG_WARN = FacesMessage.SEVERITY_WARN;
    public final static Severity MSG_INFO = FacesMessage.SEVERITY_INFO;

    public static void showMessage(Severity severity, String sMsg) {
        FacesMessage msg = new FacesMessage(severity, null, sMsg);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(null, msg);
    }

    public static void showMessage(String clientId, Severity severity,
                                   String title, String sMsg) {
        FacesMessage msg = new FacesMessage(severity, title, sMsg);
        FacesContext facesContext = FacesContext.getCurrentInstance();
        facesContext.addMessage(clientId, msg);
    }


    /**
     * @param el
     * @return
     */
    public static Object getElExpression(String el) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ELContext elContext = facesContext.getELContext();
        ExpressionFactory expressionFactory =
            facesContext.getApplication().getExpressionFactory();
        ValueExpression valueExp =
            expressionFactory.createValueExpression(elContext, el,
                                                    Object.class);
        return valueExp.getValue(elContext);
    }

    /**
     * @param el
     * @param val
     */
    public static void setElExpression(String el, Object val) {
        FacesContext facesContext = FacesContext.getCurrentInstance();
        ELContext elContext = facesContext.getELContext();
        ExpressionFactory expressionFactory =
            facesContext.getApplication().getExpressionFactory();
        ValueExpression exp =
            expressionFactory.createValueExpression(elContext, el,
                                                    Object.class);
        exp.setValue(elContext, val);
    }

    /**
     * @return
     */
    public static FacesContext getFacesContext() {
        return FacesContext.getCurrentInstance();
    }

    /**
     * @param iteratorName
     * @return
     */
    public static DCIteratorBinding getIteratorBinding(String iteratorName) {
        return getDCBindingContainer().findIteratorBinding(iteratorName);
    }

    /**
     * @return
     */
    public static DCBindingContainer getDCBindingContainer() {
        return (DCBindingContainer)getBindingContainer();
    }

    /**
     * @return
     */
    public static BindingContainer getBindingContainer() {
        return (BindingContainer)getElExpression("#{bindings}");
    }

    /**
     * @return
     */
    public static BindingContainer getBindings() {
        return BindingContext.getCurrent().getCurrentBindingsEntry();
    }

    public static String getCurrentUser() {
        return ADFContext.getCurrent().getSecurityContext().getUserName();
    }

    public static oracle.jbo.domain.Date getCurrentDate() {
        SimpleDateFormat sdfDate =
            new SimpleDateFormat("dd-MM-yy"); //dd/MM/yyyy
        Date now = new Date();
        Timestamp timestamp = new Timestamp(now.getTime());
        oracle.jbo.domain.Date jboDate = new oracle.jbo.domain.Date(timestamp);
        return jboDate;
    }

    public static String getResourceBundle(String resourceId) {
        return (String)Utils.getElExpression("#{adfBundle['view.ViewControllerBundle']['" +
                                             resourceId + "']}");
    }

    /**
     * TanBD
     * Lấy đường dẫn URL hiện tại
     * @return
     */
    public static String getCurrentUrl() {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext eContext = context.getExternalContext();
        ViewHandler handler = context.getApplication().getViewHandler();

        String prefix;
        Object requestObject = eContext.getRequest();
        if (requestObject instanceof HttpServletRequest) {
            prefix = getHttpUrlPrefix((HttpServletRequest)requestObject);
        } else {
            // Portlet?
            prefix = "";
        }

        String actionUrl =
            handler.getActionURL(context, context.getViewRoot().getViewId());

        return prefix + actionUrl;
    }

    /**
     * TanBD
     * Lấy tiền tố đường dẫn URL hiện tại
     * @return
     */
    private static String getHttpUrlPrefix(HttpServletRequest request) {
        StringBuilder builder = new StringBuilder(32);
        builder.append(request.getScheme());
        builder.append("://");
        builder.append(request.getServerName());
        builder.append(':');
        builder.append(request.getServerPort());

        return builder.toString();
    }

    public static int getPageSize(String iteratorName) {
        int pageSize = 20;
        String pageSizeString =
            Utils.ENUM_CAU_HINH_KHOA.PAGE_SIZE.getValue(iteratorName);
        try {
            if (pageSizeString != null) {
                pageSize = new Integer(pageSizeString);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pageSize;
    }

    public static enum ENUM_KIEU_DU_LIEU {
        NUMBER(1, "NUMBER"),
        VARCHAR(2, "VARCHAR"),
        DATE(3, "DATE"),
        LINK(7, "LINK"),
        EMAIL(8, "EMAIL"),
        CLOB(4, "CLOB"),
        BLOB(5, "BLOB"),
        FILE(6, "FILE"),
        LOGO(9, "LOGO"),
        SAN_GIAO_DICH(101, "SAN_GIAO_DICH"),
        LOAI_CHUNG_KHOAN(102, "LOAI_CHUNG_KHOAN"),
        KIEM_TOAN_VIEN(103, "KIEM_TOAN_VIEN"),
        SL_KIEM_TOAN_VIEN(104, "SL_KIEM_TOAN_VIEN"),
        IN_OUT_KIEM_TOAN_VIEN(105, "IN_OUT_KIEM_TOAN_VIEN");
        int id;
        String ma;

        private ENUM_KIEU_DU_LIEU(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public int getId() {
            return id;
        }
    }

    public static enum ENUM_BAT_BUOC {
        KHONG_BAT_BUOC(1, "KHONG_BAT_BUOC"),
        BAT_BUOC(2, "BAT_BUOC");
        int id;
        String ma;

        private ENUM_BAT_BUOC(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public int getId() {
            return id;
        }
    }

    public static enum ENUM_TRANG_THAI {
        KHONG_CONG_BO(1, "KHONG_CONG_BO"),
        CONG_BO(2, "CONG_BO");
        int id;
        String ma;

        private ENUM_TRANG_THAI(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public int getId() {
            return id;
        }

        public String getTen() {
            return Utils.getResourceBundle(ma);
        }
    }

    public static enum ENUM_DUY_NHAT {
        KHONG_DUY_NHAT(1, "KHONG_DUY_NHAT"),
        DUY_NHAT(2, "DUY_NHAT");
        int id;
        String ma;

        private ENUM_DUY_NHAT(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public int getId() {
            return id;
        }
    }

    public static enum ENUM_BAO_CAO {
        KHONG_PHAI_BAO_CAO(1, "KHONG_PHAI_BAO_CAO"),
        BAO_CAO(2, "BAO_CAO");
        int id;
        String ma;

        private ENUM_BAO_CAO(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public int getId() {
            return id;
        }
    }

    public static enum ENUM_LOAI_TRUONG_TT {
        DON_VI(1, "DON_VI"),
        BAO_CAO(2, "BAO_CAO"),
        CONG_BO_THONG_TIN(3, "CONG_BO_THONG_TIN"),
        SAN_GIAO_DICH(4, "SAN_GIAO_DICH"),
        LOAI_CHUNG_KHOAN(5, "LOAI_CHUNG_KHOAN"),
        KIEM_TOAN_VIEN(6, "KIEM_TOAN_VIEN");
        int id;
        String ma;

        private ENUM_LOAI_TRUONG_TT(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public int getId() {
            return id;
        }

        public String getTen() {
            return Utils.getResourceBundle(ma);
        }
    }

    public static enum ENUM_VI_TRI_HIEN_THI {
        TABLE(1, "TABLE"),
        SEARCH(2, "SEARCH"),
        SELECT(4, "SELECT"),
        PORTLET_TABLE(8, "PORTLET_TABLE"),
        PORTLET_SEARCH(16, "PORTLET_SEARCH"),
        PORTLET_INFO(32, "PORTLET_INFO"),
        PORTLET_SELECT(64, "PORTLET_SELECT"),
        PORTLET_TIN_TIEU_DE(128, "PORTLET_TIN_TIEU_DE"),
        PORTLET_TIN_TOM_TAT(512, "PORTLET_TIN_TOM_TAT"),
        PORTLET_TIN_INFO(1024, "PORTLET_TIN_INFO");
        int id;
        String ma;

        private ENUM_VI_TRI_HIEN_THI(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public void setMa(String ma) {
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public String getTen() {
            return Utils.getResourceBundle(ma);
        }

        public int getId() {
            return id;
        }
    }

    public static enum ENUM_CBTT_VI_TRI_HIEN_THI {
        CBTT(1, "CBTT"),
        BC(2, "BC");
        int id;
        String ma;

        private ENUM_CBTT_VI_TRI_HIEN_THI(int id, String ma) {
            this.id = id;
            this.ma = ma;
        }

        public void setMa(String ma) {
            this.ma = ma;
        }

        public String getMa() {
            return ma;
        }

        public String getTen() {
            return Utils.getResourceBundle(ma);
        }

        public int getId() {
            return id;
        }
    }


    public static enum ENUM_CAU_HINH_KHOA {
        FILE_ROOT("FILE_ROOT"),
        DLCT_DIR("DLCT_DIR"),
        DTVB_DIR("DTVB_DIR"),
        PAKN_DIR("PAKN_DIR"),
        APTC_DIR("APTC_DIR"),
        TTHC_DIR("TTHC_DIR"),
        KNTC_DIR("KNTC_DIR"),
        PAGE_SIZE("PAGE_SIZE");
        String khoa;

        private ENUM_CAU_HINH_KHOA(String khoa) {
            this.khoa = khoa;
        }

        public String getValue(String iteratorName) {
            DCIteratorBinding it = Utils.getIteratorBinding(iteratorName);
            it.setRangeSize(-1);
            it.executeQuery();
            RowIterator rowIterator =
                it.findRowsByAttributeValues(new String[] { "Khoa" },
                                             new Object[] { khoa });
            if (rowIterator.hasNext()) {
                Row row = rowIterator.next();
                return (String)row.getAttribute("GiaTri");
            }
            return null;
        }

        private String khoaHt = "/c:/root";

        public String KHOA_HT() {
            return khoaHt;
        }

        private String khoaAptcImage = "aptc/images/";

        public String KHOA_APTC_IMAGE() {
            return khoaAptcImage;
        }

        private String khoaAptcFile = "aptc/file/";

        public String KHOA_APTC_FILE() {
            return khoaAptcFile;
        }

        private String khoaTthcFile = "tthc/file/";

        public String KHOA_TTHC_FILE() {
            return khoaTthcFile;
        }

        public String getKhoa() {
            return khoa;
        }
    }

    public static enum ENUM_MA_UNG_DUNG {
        APTC(1),
        PAKN(2),
        TTPH(3),
        DLCT(4),
        TTHC(5),
        DTVB(6),
        KNTC(7);
        Number maUngDung;

        private ENUM_MA_UNG_DUNG(int maUngDung) {
            this.maUngDung = new Number(maUngDung);
        }

        public void setMaUngDung(Number maUngDung) {
            this.maUngDung = maUngDung;
        }

        public Number getMaUngDung() {
            return maUngDung;
        }
    }

    /**
     * TanBD
     * Đặt lại current row cho table
     * @param se
     * @param viewObjectName
     */
    public static void rowSelected(SelectionEvent se, String viewObjectName) {
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        OV.getIteratorBinding().setCurrentRowIndexInRange((Integer)se.getAddedSet().toArray()[0]);
    }

    /**
     * TanBD
     * Chuyển đến trang yêu cầu
     * @param RANGE_SIZE
     * @param pageNumber
     * @param viewObjectName
     * @return
     */
    public static String goToPage(Integer RANGE_SIZE, Integer pageNumber,
                                  String viewObjectName) {
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        int prePage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        OV.getIteratorBinding().getNavigatableRowIterator().scrollRange(RANGE_SIZE *
                                                                        (pageNumber -
                                                                         prePage));
        return null;
    }

    /**
     * TanBD
     * Chuyển đến trang cuối cùng
     * @param RANGE_SIZE
     * @param viewObjectName
     * @return
     */
    public static String goLastPage(Integer RANGE_SIZE,
                                    String viewObjectName) {
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        long lastPageNum =
            Math.max(1, (OV.getIteratorBinding().getEstimatedRowCount() - 1) /
                     RANGE_SIZE + 1);
        if (lastPageNum <= 1)
            return null;
        int prePage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        OV.getIteratorBinding().getNavigatableRowIterator().scrollRange((int)(RANGE_SIZE *
                                                                              (lastPageNum -
                                                                               prePage)));
        OV.setCurrentRowAtIndex(0);
        return null;
    }

    /**
     * TanBD
     * Kiểm tra có phải trang cuối hay không
     * @param RANGE_SIZE
     * @param viewObjectName
     * @return
     */
    public static boolean isLastEnabled(Integer RANGE_SIZE,
                                        String viewObjectName) {
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        long lastPageNum =
            Math.max(1, (OV.getIteratorBinding().getEstimatedRowCount() - 1) /
                     RANGE_SIZE + 1);
        long currentPage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        return currentPage < lastPageNum;
    }

    /**
     * TanBD
     * Kiểm tra có phải trang đầu tiên hay không
     * @param RANGE_SIZE
     * @param viewObjectName
     * @return
     */
    public static boolean isFirstEnabled(Integer RANGE_SIZE,
                                         String viewObjectName) {
        boolean isFirst = true;
        JUCtrlRangeBinding OV = getViewObject(viewObjectName);
        long currentPage =
            OV.getIteratorBinding().getNavigatableRowIterator().getRangeStart() /
            RANGE_SIZE + 1;
        if (currentPage == 1) {
            isFirst = false;
        }
        return isFirst;
    }

    /**
     * TanBD
     * Lấy đối tượng ViewObject trả về kiểu JUCtrlRangeBinding
     * @param viewObjectName
     * @return
     */
    public static JUCtrlRangeBinding getViewObject(String viewObjectName) {
        BindingContext bindingCtx = BindingContext.getCurrent();
        BindingContainer bindings = bindingCtx.getCurrentBindingsEntry();
        return (JUCtrlRangeBinding)bindings.getControlBinding(viewObjectName);
    }
}
